/**     
* @Title: MyAccessDecisionManager.java   
* @Package me.security.example.security   
* @Description: TODO   
* @author xaoyaoyao
* @date 2017年8月23日 下午12:23:10
*/
package me.security.example.security;

import java.util.Collection;

import javax.servlet.http.HttpServletRequest;

import org.springframework.security.access.AccessDecisionManager;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.authentication.InsufficientAuthenticationException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.web.FilterInvocation;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import org.springframework.stereotype.Service;

/**
 * @ClassName: MyAccessDecisionManager
 * @Description: TODO
 * @author xaoyaoyao
 * @date 2017年8月23日 下午12:23:10
 * 
 */
@Service
public class MyAccessDecisionManager implements AccessDecisionManager {

	@Override
	public void decide(Authentication authentication, Object object, Collection<ConfigAttribute> configAttributes)
			throws AccessDeniedException, InsufficientAuthenticationException {
		HttpServletRequest request = ((FilterInvocation) object).getHttpRequest();
		String url, method;
		AntPathRequestMatcher matcher;
		for (GrantedAuthority ga : authentication.getAuthorities()) {
			if (ga instanceof MyGrantedAuthority) {
				MyGrantedAuthority urlGrantedAuthority = (MyGrantedAuthority) ga;
				url = urlGrantedAuthority.getPermissionUrl();
				method = urlGrantedAuthority.getMethod();
				matcher = new AntPathRequestMatcher(url);
				if (matcher.matches(request)) {
					// 当权限表权限的method为ALL时表示拥有此路径的所有请求方式权利。
					if (method.equals(request.getMethod()) || "ALL".equals(method)) {
						return;
					}
				}
				// 未登录只允许访问login 页面
			} else if (ga.getAuthority().equals("ROLE_ANONYMOUS")) {
				matcher = new AntPathRequestMatcher("/login");
				if (matcher.matches(request)) {
					return;
				}
			}
		}
		throw new AccessDeniedException("Access Denied");
	}

	@Override
	public boolean supports(ConfigAttribute arg0) {
		return true;
	}

	@Override
	public boolean supports(Class<?> arg0) {
		return true;
	}
}
